#include <cstdlib>
#include <vector>
#include <string>
#include <cstring>
#include <pthread.h>
#include "BlockQueue.hpp"
#include "Task.hpp"

// 线程传递的参数
struct ThreadData
{
    BlockQueue<Task> *_cp;    // 生产者消费者模型对象
    std::string _thread_name; // 线程名称

    // 构造函数
    ThreadData(BlockQueue<Task> *cp, std::string name)
        : _cp(cp), _thread_name(name) {}
};
// 消费者线程函数
void *Costomer(void *arg)
{
    // 接收参数
    ThreadData *data = (ThreadData *)arg;

    while (true)
    {
        // 获取任务
        Task task;
        data->_cp->PoP(&task);
        std::cout << data->_thread_name << " run task : ";
        // 执行任务
        task();
    }
    return nullptr;
}
// 生产者线程参数
void *Productor(void *arg)
{
    // 接收参数
    ThreadData *data = (ThreadData *)arg;

    while (true)
    {
        // 生产任务数据
        int data1 = rand() % 10;
        int data2 = rand() % 10;
        char op = str[rand() % str.size()];
        Task task(data1, data2, op);
        // 将任务放入队列
        data->_cp->Push(task);
        std::cout << data->_thread_name << " push task into queue : " << data1 << op << data2 << std::endl;
    }
    return nullptr;
}

int main()
{
    // 生产随机数种子
    srand((uint16_t)time(nullptr) ^ getpid() ^ pthread_self());
    // 创建生产者消费者模型对象
    BlockQueue<Task> *cp = new BlockQueue<Task>();

    // 创建生产者消费者线程
    std::vector<pthread_t> custumer_thread(5);
    std::vector<pthread_t> productor_thread(5);
    // 消费者
    for (int i = 0; i < 5; i++)
    {
        // 线程id
        pthread_t tid;
        // 构造线程参数
        std::string thread_name = "customer-" + std::to_string(i);
        ThreadData data(cp, thread_name);
        // 创建线程
        pthread_create(&tid, nullptr, Costomer, &data);
        // 放入数组中
        custumer_thread.push_back(tid);
    }
    // 生产者
    for (int i = 0; i < 5; i++)
    {
        // 线程id
        pthread_t tid;
        // 构造线程参数
        std::string thread_name = "productor-" + std::to_string(i);
        ThreadData data(cp, thread_name);
        // 创建线程
        pthread_create(&tid, nullptr, Productor, &data);
        // 放入数组中
        productor_thread.push_back(tid);
    }
    
    // 线程等待
    for (size_t i = 0; i < custumer_thread.size(); ++i)
    {
        if (pthread_join(custumer_thread[i], nullptr) != 0)
        {
            std::cerr << "等待消费者线程结束失败" << std::endl;
        }
    }

    for (size_t i = 0; i < productor_thread.size(); ++i)
    {
        if (pthread_join(productor_thread[i], nullptr) != 0)
        {
            std::cerr << "等待生产者线程结束失败" << std::endl;
        }
    }

    // 释放资源
    delete cp;

    return 0;
}